
import { WebSocketServer, WebSocket } from 'ws';
import { IncomingMessage } from 'http';
import userService from '../services/user.service';
import processMessage, { sendNotice } from './process';
import messageService from '../services/message.service';
import friendService from '../services/friend.service';
import requestService from '../services/request.service';
import { HEARTBEAT_TIMEOUT } from '../constants/normal.constants';
import groupService from '../services/group.service';

export const wsClients = new Map<string, WebSocket>();

function setupWebSocketServer(wss: WebSocketServer) {
    wss.on('connection', async (ws: WebSocket, req: IncomingMessage) => {
        const userId = req.auth.userId;
        const logginWs = wsClients.get(userId)
        if (logginWs) {
            sendNotice({ type: 'warning', message: 'another device logged in', receiverId: userId })
            logginWs.close(1008, 'Already logged in');
        }
        console.log('new client connected:', userId);
        ws.userId = userId;
        wsClients.set(userId, ws);
        const keys = Array.from(wsClients.keys());
        console.log('当前在线列表', keys);
        setHeartbeatTimeout(ws)
        messageHandler(ws)
        closeHandler(ws)
        initialMessage(ws)
    });
}
function setHeartbeatTimeout(ws: WebSocket) {
    let timeoutId = setTimeout(() => {
        console.log('Heartbeat timeout');
        ws.close(1008, 'Heartbeat timeout');
    }, HEARTBEAT_TIMEOUT);
    ws.heartbeatTimeout = timeoutId;
}
function messageHandler(ws: WebSocket) {
    ws.on('message', function incoming(msg) {
        let message = msg.toString()
        if (message == 'heartbeat') {
            if (ws.heartbeatTimeout) {
                clearTimeout(ws.heartbeatTimeout);
            }
            setHeartbeatTimeout(ws);
        }
        else {
            const request = JSON.parse(message);
            console.log('receivied client message:', request);
            processMessage(request)
        }
    });
}
function closeHandler(ws: WebSocket) {
    ws.on('close', async () => {
        console.log('WebSocket connection closed');
        if (ws.heartbeatTimeout) {
            clearTimeout(ws.heartbeatTimeout);
        }
        await userService.logout(ws.userId);
        wsClients.delete(ws.userId)
    });
}
//初始化发送
async function initialMessage(ws: WebSocket) {
    //offline messages
    const userInfo = await userService.findUserByUserId(ws.userId)
    const messageData = await messageService.getOfflineMessages(ws.userId, userInfo.lastLogin)
    ws.send(JSON.stringify({
        dataType: 'messages',
        data: messageData
    }))

    //friends 
    const friendData = await friendService.getFriends(ws.userId)
    ws.send(JSON.stringify({
        dataType: 'contacts',
        data: friendData
    }))

    //groups
    const groupData = await groupService.getUserGroups(ws.userId)
    ws.send(JSON.stringify({
        dataType: 'contacts',
        data: groupData
    }))

    //requests
    const requestData = await requestService.getPendingRequests(ws.userId)
    ws.send(JSON.stringify({
        dataType: 'requests',
        data: requestData
    }))
}
export default setupWebSocketServer